//
//  P2PMessenger.m
//  RunSketch
//
//  Created by Brian on 10/21/09.
//  Copyright 2009 Tellart. All rights reserved.
//

#import "P2PMessenger.h"

#define P2PMessengerSessionID @"nmptp"
#define kConnectTimeout (NSTimeInterval)10.0

@implementation P2PMessenger

@synthesize myDelegate, myPeerID, dataToSend, connected;

-(id)init
{
    if (self = [super init])
    {
        NSLog(@"[P2PMessenger init]");
        
        mySession = [[GKSession alloc]
                    initWithSessionID:P2PMessengerSessionID
                    displayName:nil
                    sessionMode:GKSessionModePeer];
                    
        mySession.delegate = self;
        [mySession setDataReceiveHandler:self withContext:nil];
        //[mySession retain];
    }
    return self;
}

//deallocate the NADAMobileIOHelper
- (void)dealloc {
    //[mySession release];
    
    [dataToSend release];
    
    [super dealloc];
}

/*******************************************************************************************************************
*/

- (P2PMessengerStatus) startAcceptingWithDelgate:(id <P2PMessengerDelegate>)delegate
{
    if (self.myPeerID == nil) return kP2PMessengerStatus_InvalidPeerID;
    if (mySession.available) return kP2PMessengerStatus_OK; //already accepting
    
    self.myDelegate = delegate;
    self.dataToSend = nil;
    
    [mySession    initWithSessionID:P2PMessengerSessionID
                displayName:self.myPeerID
                sessionMode:GKSessionModePeer];
    
    mySession.available = YES;
    
    return kP2PMessengerStatus_OK;
}

- (P2PMessengerStatus) stopAccepting
{
    mySession.available = NO;
    self.connected = NO;
    [mySession disconnectFromAllPeers];
    return kP2PMessengerStatus_OK;
}

- (void) connectForSending:(NSString *)toID
{
    if (!self.connected) {
        [mySession    initWithSessionID:P2PMessengerSessionID
                    displayName:self.myPeerID
                    sessionMode:GKSessionModePeer];
        mySession.available = YES;
        [mySession connectToPeer:toID withTimeout:kConnectTimeout];
    }
}

- (void) doSend:(NSString *)toID
{
    if (self.dataToSend == nil) return;
    if (!self.connected) return;
    
    NSError *error = [NSError alloc];
    if (![mySession  sendData:self.dataToSend
                toPeers:[NSArray arrayWithObject:toID]
                withDataMode: GKSendDataReliable
                error:&error])
    {
        NSLog(@"P2PMessenger: sendData error: %@", [error description]);
    }
    
    self.dataToSend = nil;
}

- (P2PMessengerStatus) sendData:(NSData *)data to:(NSString *)toID
{
    if (self.myPeerID == nil) return kP2PMessengerStatus_InvalidPeerID;

    self.dataToSend = data;

    [self connectForSending:toID];
    [self doSend:toID];

    return kP2PMessengerStatus_OK;
}

/**************************************************************************************************************
 *
 * GKSessionDelegate methods
 *
 */

- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state {
	switch (state) {
		case GKPeerStateConnected:
            NSLog(@"P2PMessenger: didChangeState: GKPeerStateConnected");
            //TODO
			break;
		case GKPeerStateConnecting:
            NSLog(@"P2PMessenger: didChangeState: GKPeerStateConnected");
            break;
		case GKPeerStateAvailable:
            NSLog(@"P2PMessenger: didChangeState: GKPeerStateAvailable");
            //TODO
			break;
		case GKPeerStateUnavailable:
            NSLog(@"P2PMessenger: didChangeState: GKPeerStateUnavailable");
            //TODO
			break;
		case GKPeerStateDisconnected:
            NSLog(@"P2PMessenger: didChangeState: GKPeerStateDisconnected");
            //TODO
			break;
	}
}
- (void)session:(GKSession *)session didReceiveConnectionRequestFromPeer:(NSString *)peerID {
    NSLog(@"P2PMessenger: didReceiveConnectionRequestFromPeer");
    if (session.available) {
        [session acceptConnectionFromPeer:peerID error:nil];
        self.connected = YES;
        [self doSend:peerID];
    }
}

- (void)session:(GKSession *)session connectionWithPeerFailed:(NSString *)peerID withError:(NSError *)error {
    //TODO
    self.connected = NO;
    NSLog(@"P2PMessenger: connectionWithPeerFailed: peer=%@ error=%@", peerID, error);
}

- (void)session:(GKSession *)session didFailWithError:(NSError *)error {
    //TODO
    self.connected = NO;
    NSLog(@"P2PMessenger: didFailWithError: error=%@", error);
}

/**************************************************************************************************************
 *
 * GKSession data receiver
 *
 */
- (void)receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context
{
    [self.myDelegate messenger:self didReceiveData:data from:peer];
}

@end
